#include "aes_tcp_lib.h"

#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/watchdog.h>
#include <unistd.h>
#include<openssl/rsa.h>
#include<openssl/pem.h>
#include<openssl/err.h>

#include "QObject"
#define CRYPT_CACHE_SIZE 1024 * 16
#define MSG_CACHE_SIZE 1024 * 16
enum DOWN_TYPE{

    ST_PACK = 0,
    ST_FILE
};

aes_tcp_lib::aes_tcp_lib()
{
    server_ip.clear();
    msg_port = 0;
}
aes_tcp_lib * aes_tcp_lib::create_aes_tcp()
{
    return new aes_tcp_lib;

}
void aes_tcp_lib::lus_set_order(qint8 order)
{
    byte_order = order;
}
void aes_tcp_lib::aes_tcp_close(void)
{

    msg_tcp_socket->disconnectFromHost();

}

void aes_tcp_lib::aes_tcp_init(void)
{

    parse = new lus_prase;
    parse->init_prase();

    if(!parse->server_ip.isEmpty()){
        server_ip = parse->server_ip;
        qDebug()<<"set server ip from prase: " << server_ip;
    }
    if(!parse->server_port.isEmpty()){
        msg_port=parse->server_port.toInt();
        qDebug()<<"set server port from prase: "<<msg_port;
    }

    lus_version = "0";
    lus_group_id = "0";

    if((!parse->client_version.isEmpty()) && (!parse->my_group_id.isEmpty())){
       lus_version = parse->client_version;
       lus_group_id = parse->my_group_id;
    }

    /*网络初始化*/
    if(server_ip.isEmpty())
        server_ip = "beijg.3322.org";

    if(msg_port == 0)
        msg_port = 9527;

    msg_blockSize = 0;
    file_type=0;
    totalBytes=0;
    bytesReceived=0;
    fileNameSize=0;

    wd_fd = 0;
    wd_timeout = 10;

    UCHAR aes_key_tmp[16] = {0x22, 0xa2, 0x13, 0xe2, 0x22, 0xa2, 0x12, 0x20, 0x22, 0x15, 0x22, 0xda, 0x67, 0x22, 0x32, 0x22 };
    for(int i=0; i<16; i++){
        aes_key[i] = aes_key_tmp[i];
    }

    fix_id.clear();
    to_addr.clear();

    QFileInfo f_i("fix_id");
    if(!f_i.isFile()){

        QDateTime time = QDateTime::currentDateTime();
        QString id = time.toString("yyyy.MM.dd-hh:mm:ss-");
        qsrand(time.time().msec()+time.time().second()*1000);

        QString rand = QString::number(qrand()%100);
        id += rand;

        QByteArray b_id = id.toLatin1().toBase64();

        QFile file("fix_id");
        file.open(QIODevice::WriteOnly);
        file.write(b_id);
        file.close();

        if(debug_enable)
            qDebug()<<"creat fix id "<<b_id;

    }

    QFile file("fix_id");
    file.open(QIODevice::ReadOnly);
    fix_id=file.readAll();
    file.close();

    msg_tcp_socket = new QTcpSocket();
    f_tcpSocket	   = new QTcpSocket();
    aes = new TAesClass;

    aes_cache = new char[CRYPT_CACHE_SIZE];
    /*缓冲init*/
    tcp_msg_data_cache = new char[MSG_CACHE_SIZE];

    timer_connect = new QTimer(this);
    timer_heart = new QTimer(this);

    s_file_md5 = new QString;
    inBlock = new QByteArray;
    fileName = new QString;

    BIGNUM *bne=BN_new();
    lus_rsa = RSA_new();

    BN_set_word(bne,RSA_F4);
    if(RSA_generate_key_ex(lus_rsa, 2048, bne, NULL) == NULL){
        qDebug()<<"generate rsa error";
        exit(-1);
    }
    FILE *fp = fopen("rsa_pub", "w");
    PEM_write_RSAPublicKey(fp, lus_rsa);
    fclose(fp);

    QFile rsa_file("rsa_pub");
    rsa_file.open(QIODevice::ReadOnly);
    local_pub_rsa = rsa_file.readAll();
    rsa_file.close();
    qDebug()<<"local pub: \n"<<local_pub_rsa;
    server_pub_rsa = nullptr;

    connect(msg_tcp_socket,SIGNAL(error(QAbstractSocket::SocketError)),
             this,SLOT(displayError(QAbstractSocket::SocketError)));
    /*aes init*/
    UCHAR *p = aes_key;
    aes->InitializePrivateKey(16, p); //进行初始化

    /*掉线自动重连定时器*/
    connect( timer_connect, SIGNAL( timeout() ), this, SLOT( timer_auto_connect() ) );
    timer_connect->stop();

    /*心跳*/
    connect( timer_heart, SIGNAL( timeout() ), this, SLOT( timer_heart_keep()) );
    timer_heart->stop();

    connect(msg_tcp_socket,SIGNAL(readyRead()),this,SLOT(readMessage_msg()));

     /*自动重连处理*/
    connect(msg_tcp_socket,SIGNAL(connected()),this,SLOT(disable_reconnect()));
    connect(msg_tcp_socket,SIGNAL(disconnected()),this,SLOT(enable_reconnect()));

    connect(parse, SIGNAL(lus_requst_send(QByteArray)), this, SLOT(do_prase_requst(QByteArray)));
     /*连接到服务器*/
    timer_connect->start(1000);

}

aes_tcp_lib::~aes_tcp_lib()
 {

    free(tcp_msg_data_cache);

 }
void aes_tcp_lib::timer_heart_keep(void)
{
    static uint32_t time_cnt=0;
    time_cnt ++;

    QByteArray cmd = "<lus_cmd body=\"heart\"  paral=\"120\" />";

    if(debug_enable)
        qDebug()<<"send heart!";
    if(time_cnt == 80){
        time_cnt=0;
        sendMessage(cmd, ENCRYPT_YES);
    }
}
void aes_tcp_lib::lus_config_dog(uint32_t freq, QString path="/dev/watchdog")
{
		
	if(freq != 0){
		wd_timeout = freq;
	}
	//初始化看门狗
	if(wd_fd == 0){
		wd_fd = open(path.toLatin1().data(), O_RDWR);
	}else{
		qDebug()<<"dog was ok! skip";
	}

	if(wd_fd > 0){
		qDebug()<<"init watchdog freq: "<<wd_timeout;
		ioctl(wd_fd, WDIOC_SETTIMEOUT, &wd_timeout);
		ioctl(wd_fd, WDIOC_GETTIMEOUT, &wd_timeout);
	}else{
		qDebug()<<"set dog error!";
	}

}

void aes_tcp_lib:: lus_feed_dog(uint32_t feed)
{
	
    if(wd_fd>0){
		if(feed == 0){
			feed = 10;
		}
        ::write(wd_fd, "yin", feed);
    }else{
        qDebug()<<"write dog error";
    }
}
void aes_tcp_lib::do_prase_requst(QByteArray msg)
{
    sendMessage(msg, ENCRYPT_YES);
}
void aes_tcp_lib::displayError(QAbstractSocket::SocketError)
{
    qDebug() << msg_tcp_socket->errorString(); //输出错误信息
}

void aes_tcp_lib::newConnect()
{
    msg_blockSize = 0; //初始化其为0

    msg_tcp_socket->abort(); //取消已有的连接

    /*连接到主机，这里从界面获取主机地址和端口号*/
     msg_tcp_socket->connectToHost(server_ip, msg_port);

     connect(msg_tcp_socket,SIGNAL(readyRead()),this,SLOT(readMessage_msg()));

     /*自动重连处理*/
     //connect(msg_tcp_socket,SIGNAL(connected()),this,SLOT(disable_reconnect()));
     //connect(msg_tcp_socket,SIGNAL(disconnected()),this,SLOT(enable_reconnect()));
}
/*新建文件传输连接*/
void aes_tcp_lib::newFileConnect()
{
    /*等待上一个传输完成*/
    if(debug_enable)
        qDebug()<<"connect to file tcp";

    f_tcpSocket->abort(); //取消已有的连接
    //连接到主机，这里从界面获取主机地址和端口号
    f_tcpSocket->connectToHost(server_ip, 9528);
    connect(f_tcpSocket,SIGNAL(readyRead()),this,SLOT(updateServerProgress()));
    connect(f_tcpSocket,SIGNAL(connected()),this,SLOT(f_connected()));
    down_status = DOWN_ING;
}

int aes_tcp_lib::rsa_encrypt(char *str_in, char *str_out)
{
    int len = 0;
    int rsa_len = 0;

    len = strlen(str_in);
    rsa_len = RSA_size(lus_rsa);

    if (RSA_public_encrypt(rsa_len, (unsigned char *)str_in, (unsigned char*)str_out, lus_rsa, RSA_NO_PADDING) < 0) {
        return -1;
    }

    return len;
}

int aes_tcp_lib::rsa_decrypt(char *str_in, char *str_out)
{
    int rsa_len = 0;

    rsa_len = RSA_size(server_pub_rsa);

    if (RSA_private_decrypt(rsa_len, (unsigned char *)str_in, (unsigned char*)str_out, server_pub_rsa, RSA_NO_PADDING) < 0) {
        return -1;
    }

    return rsa_len;
}

void aes_tcp_lib::f_connected(void)
{
    qDebug()<<"file socket connected";

    QString cmd = QString("<%1,%2>").arg("id").arg(fix_id);

    do_send_msg(f_tcpSocket, cmd.toLatin1(), ENCRYPT_YES);
}
void aes_tcp_lib::lus_set_debug(bool sw)
{
    debug_enable = sw;
}
void aes_tcp_lib::lus_set_server(QString ip="beijg.3322.org", quint16 port=9527)
{
    server_ip = ip;
    msg_port = port;
}
void aes_tcp_lib::lus_set_prase(bool sw)
{
    parse_enable = sw;
}
void aes_tcp_lib::lus_set_dst(QString addr)
{
    to_addr = addr;
}
QString aes_tcp_lib::lus_get_fix_id(void)
{
    return fix_id;
}
uint8_t aes_tcp_lib::lus_get_down_status(void)
{
    return down_status;
}

/*接收文件数据*/
void aes_tcp_lib::updateServerProgress()
{

   QDataStream in(f_tcpSocket);
   in.setVersion(QDataStream::Qt_4_6);
    qDebug()<<"file socket!" << bytesReceived;
   if(bytesReceived <= sizeof(qint64)*3)
   {
       qDebug()<< "head info";
       //如果接收到的数据小于16个字节，那么是刚开始接收数据，我们保存到//来的头文件信息
       if((f_tcpSocket->bytesAvailable() >= sizeof(qint64)*3)
           && (fileNameSize == 0))
       { //接收数据总大小信息和文件名大小信息
           in >>file_type>> totalBytes >> fileNameSize;

           if(debug_enable)
               qDebug()<< file_type <<" "<< totalBytes<< " "<<fileNameSize;

           bytesReceived += sizeof(qint64) * 3;
       }
       if((f_tcpSocket->bytesAvailable() >= fileNameSize)
           && (fileNameSize != 0))
       {  //接收文件名，并建立文件
           in >> *fileName;

           if(debug_enable)
                qDebug() << tr("recive file %1 ...").arg(*fileName);

           bytesReceived += fileNameSize;

           if(file_type == ST_FILE){
                localFile= new QFile(file_save_path + (*fileName));
           }else {
                localFile= new QFile("/lus/down/" + (*fileName));
           }

           if(!localFile->open(QFile::WriteOnly))
           {
                qDebug() << "open file error!";
                return;
           }
       }
       else return;
   }



   if(bytesReceived < totalBytes)
   {  //如果接收的数据小于总数据，那么写入文件
      bytesReceived += f_tcpSocket->bytesAvailable();

      *inBlock= f_tcpSocket->readAll();
      localFile->write(*inBlock);
      inBlock->resize(0);
   }
//更新进度条

   if(bytesReceived == totalBytes )
   { //接收数据完成时
       bytesReceived = 0;
       fileNameSize = 0;
       totalBytes = 0;

        f_tcpSocket->close();
        localFile->close();

        qDebug()<<"recive file ok";

        recive_file_finally();

   }
}

/*文件接收完成后续处理*/
void aes_tcp_lib::recive_file_finally(void)
{

    /*进行MD5校验*/
    if(!s_file_md5->isEmpty())
    {
        QString file_path;
        if(file_type == ST_FILE){
            file_path = file_save_path + (*fileName);
            qDebug()<<"check file md5, file_save_path: "<<file_save_path;
        }else{
            file_path = "/lus/down/" + (*fileName);
        }
        QString n_md5 = get_file_md5(file_path);

        if(n_md5 == *s_file_md5){

            if(debug_enable)
                qDebug() << "file md5 check ok";

        }else{

             qDebug() << "file md5 check fail: "<<n_md5;
             return;
        }


    }

    if(file_type == ST_PACK){
        parse->lus_exec_pack(*fileName);
        qDebug()<<"exec pack!";
    }
    down_status = DOWN_OK;

}

QString aes_tcp_lib::get_file_md5(QString str_path)
 {
    QByteArray b_md5;
     QFile theFile(str_path);
     if(theFile.open(QIODevice::ReadOnly)){
        b_md5 = QCryptographicHash::hash(theFile.readAll(), QCryptographicHash::Md5);
        theFile.close();
     }else{

         b_md5 = "open: "+str_path.toLatin1();
         b_md5 += "FAIL";
     }
    return b_md5.toHex().constData();
 }

/*自动重连*/
void aes_tcp_lib::enable_reconnect(void)
{
    timer_connect->start(4000); //10s
    timer_heart->stop();
    RSA_free(server_pub_rsa);
    emit aes_tcp_disconnected();
}

void aes_tcp_lib::disable_reconnect(void)
{
   timer_connect->stop();
}

/*定时器自动调用此函数*/
void aes_tcp_lib::timer_auto_connect(void)
{

    msg_blockSize = 0; //初始化其为0

    msg_tcp_socket->abort(); //取消已有的连接

    //连接到主机，这里从界面获取主机地址和端口号
    msg_tcp_socket->connectToHost(server_ip,  msg_port);
}

void aes_tcp_lib::lus_send_user_msg(QString type, QString to_addr, QString body)
{

    QString cmd = "<lus_user_msg type=\"@1\" to_addr=\"@2\" body=\"@3\" />";

    if(type.isEmpty()){
        qDebug()<<"lus_send_user_msg: type is null";
        return;
    }

    cmd.replace("@1", type);

     if(body.isEmpty()){
        qDebug()<<"lus_send_user_msg: body is null";
        return;
    }

     cmd.replace("@3", body);


     if(to_addr.isEmpty())
        qDebug()<<"lus_send_user_msg: to addr is null";

     cmd.replace("@2", to_addr);

     sendMessage(cmd.toLatin1(), ENCRYPT_YES);

}

void aes_tcp_lib::lus_send_raw_msg(QByteArray b_data, quint8 encrypt_c)
{
    do_send_msg(msg_tcp_socket, b_data, encrypt_c);
}

void inline aes_tcp_lib::do_send_msg(QTcpSocket *socket,QByteArray b_data, quint8 encrypt_c)
{
    if((socket->state() == QAbstractSocket::ConnectedState)){

        if((!to_addr.isEmpty()) && (b_data.indexOf("lus_user_msg") != -1) &&(b_data.indexOf("to_addr") == -1)){

            QByteArray addr = " to_addr=\"@@\" ";

            addr.replace("@@", to_addr.toLatin1());
            b_data.insert(b_data.size()-2, addr);
            qDebug()<<"auto add to_addr";
        }

        //用于暂存我们要发送的数据
        QByteArray block;
        //使用数据流写入数据
        QDataStream out(&block,QIODevice::WriteOnly);
        out.setVersion(QDataStream::Qt_5_6);
        if(byte_order == LITTLE){
            out.setByteOrder(QDataStream::LittleEndian);
        }
        out<<(quint32) 0;
        out<<(quint32) b_data.size();
        if(encrypt_c == ENCRYPT_YES){

            int en_len = 0;

            en_len = RSA_public_encrypt(b_data.size(), (const unsigned char *)b_data.data(), (unsigned char *)aes_cache, server_pub_rsa, RSA_PKCS1_OAEP_PADDING);

            if(en_len == -1){
                ERR_load_crypto_strings();
                char errBuf[512];
                ERR_error_string_n(ERR_get_error(), errBuf, sizeof(errBuf));
                qDebug() <<QString("rsa error: ")<< errBuf;
            }

            if(debug_enable)
                qDebug() << "en_len" << en_len <<"b_data size "<< b_data.size();

            //设置数据流的版本，客户端和服务器端使用的版本要相同

            out<<(quint8) 0x12;
            out.writeRawData(aes_cache, (sizeof(char))* en_len);       //原始写！！

            out.device()->seek(0);
            out<<(quint32)((en_len+sizeof(quint32)*2+sizeof(quint8)));

        }else{

            out<<(quint8) 0x7;
            out.writeRawData(b_data, b_data.size());       //原始写！！
            out.device()->seek(0);
            out<<(quint32)(b_data.size()+sizeof(quint32)*2+sizeof (quint8));

        }

        socket->write(block);
        socket->flush();

    }else{

        qDebug()<<"socket status error!";
    }

}

/*for old version*/
void aes_tcp_lib::sendMessage(QByteArray b_data, quint8 encrypt_c)
{
    do_send_msg(msg_tcp_socket, b_data, encrypt_c);
}

void aes_tcp_lib::readMessage_msg()
{

    QDataStream in(msg_tcp_socket);
    quint8 encrypt_flag = 0xff;
    quint32 load_size = 0;

    //设置数据流版本，这里要和服务器端相同
    in.setVersion(QDataStream::Qt_5_6);
    if(byte_order == LITTLE){
        in.setByteOrder(QDataStream::LittleEndian);
    }
    if(msg_blockSize==0) //如果是刚开始接收数据,新tcp帧
    {
       //判断接收的数据是否有两字节，也就是文件的大小信息
       //如果有则保存到msg_blockSize变量中，没有则返回，继续接收数据
       if(msg_tcp_socket->bytesAvailable() < (int)(sizeof(quint32)*2+sizeof (quint8))) {

           return;
       }
           in >> msg_blockSize;		//读取数据长度
           in >> load_size;
           in >> encrypt_flag;		//读取加密位

           if(debug_enable)
               qDebug()<<msg_blockSize<<" "<< load_size <<" "<<encrypt_flag;
           /*非法数据格式，jump*/
           if((encrypt_flag != ENCRYPT_NO ) && (encrypt_flag != ENCRYPT_YES)){
                msg_blockSize = 0;
                qDebug()<<"check format error";
                return;
           }
    }

    if(msg_tcp_socket->bytesAvailable() < (msg_blockSize-sizeof (quint32)*2-sizeof (quint8))) return;
    //如果没有得到全部的数据，则返回，继续接收数据

    int real_data_len = msg_blockSize-sizeof (quint32)*2-sizeof (quint8);

    if(real_data_len > MSG_CACHE_SIZE){
        qDebug()<<"too big data to cache";
        return;
    }
    in.readRawData(tcp_msg_data_cache, real_data_len);    //原始读取！

    QByteArray byte_data;
    QDataStream b_in(&byte_data, QIODevice::WriteOnly);

    if(encrypt_flag == ENCRYPT_YES && server_pub_rsa != nullptr){
        //将接收到的数据存放到变量中
        if(real_data_len > CRYPT_CACHE_SIZE){
            qDebug()<<"too big to uncrypt";
            return;
        }
        int un_size = 0;
   /*
        //解密
        un_size = aes->OnAesUncrypt((LPVOID)tcp_msg_data_cache, (DWORD)sizeof(char)* real_data_len,(LPVOID)aes_cache); //进行解密
        if(debug_enable)
            qDebug()<<"uncrypt size: "<<un_size;
*/
        int rsa_len = RSA_size(lus_rsa);
        un_size = RSA_private_decrypt(real_data_len, (const unsigned char *)tcp_msg_data_cache, (unsigned char *)aes_cache, lus_rsa, RSA_PKCS1_OAEP_PADDING);
        if(un_size == 0){
                qDebug()<<"uncrypt error";
                return;
            }

         b_in.writeRawData(aes_cache, load_size);

    }else if(encrypt_flag == ENCRYPT_NO){

        b_in.writeRawData(tcp_msg_data_cache, real_data_len);

    }

    if(!default_do_cmd(byte_data))
        emit read_msg(byte_data);

    msg_blockSize = 0;
    if(msg_tcp_socket->bytesAvailable()>10)readMessage_msg();

}

/*
void aes_tcp_lib::readMessage_big()
{
    QDataStream in(big_tcp_socket);

    quint8 encrypt_flag = 1;

    //设置数据流版本，这里要和服务器端相同
    in.setVersion(QDataStream::Qt_5_6);

    if(big_blockSize==0) //如果是刚开始接收数据
    {
       //判断接收的数据是否有两字节，也就是文件的大小信息
       //如果有则保存到msg_blockSize变量中，没有则返回，继续接收数据
       if(big_tcp_socket->bytesAvailable() < (qint64)(sizeof(quint32)+sizeof (quint8))) {

           return;
       }
           in >> big_blockSize;
           in >> encrypt_flag;

           //非法数据格式，jump
           if((encrypt_flag != ENCRYPT_NO ) && (encrypt_flag != ENCRYPT_YES)){

               big_blockSize = 0;
               qDebug()<<"check format error";

                return;
           }
    }


    if(big_tcp_socket->bytesAvailable() < (big_blockSize-sizeof (quint32)-sizeof (quint8))) return;
    //如果没有得到全部的数据，则返回，继续接收数据

    int real_data_len = big_blockSize-sizeof (quint32)-sizeof (quint8);

    if(real_data_len > 1024*1024){

        qDebug()<<"too big data to big cache";
        return;
    }

    if(encrypt_flag == ENCRYPT_YES){

        qDebug()<<"big msg is not support encrypt";
        return;
    }

    in.readRawData(tcp_big_data_cache, real_data_len);    //原始读取！

    QByteArray byte_data;
    QDataStream b_in(&byte_data, QIODevice::WriteOnly);

    b_in.writeRawData(tcp_big_data_cache, real_data_len);

    emit read_msg(byte_data);

    big_blockSize = 0;

    default_do_big_cmd(byte_data);

}
*/

void aes_tcp_lib::default_do_big_cmd(QString cmd)
{
   QDomDocument xml;
   xml.setContent(cmd);
   QDomElement rootnode = xml.documentElement();

    if(rootnode.tagName() == "lus_user_msg" || rootnode.tagName() == "user_msg"){
       if(rootnode.attributeNode("type").value() == "tank_image"){

           QString image_base64 = rootnode.attributeNode("body").value();

            QByteArray Ret_bytearray;
            Ret_bytearray =QByteArray::fromBase64(image_base64.toLatin1());
           // QImage image;
           // image.loadFromData(Ret_bytearray);

           // emit image_ready(&image);

       }

        return;
   }

}

bool inline aes_tcp_lib::default_do_cmd(QByteArray cmd)
{
   QDomDocument xml;
   xml.setContent(cmd);

   QDomElement rootnode = xml.documentElement();

   if(debug_enable)
        qDebug()<<"rec: "<<cmd;
   if(parse_enable){
      parse->lus_parse_do_cmd(cmd);
   }
   if(rootnode.tagName() == "lus_init_msg"){

       server_pub_rsa = RSA_new();

       QString rsa_str = rootnode.attributeNode("key_pub").value();
       if(rsa_str.isEmpty())
           return true;

       FILE *fp = fopen("/tmp/pub", "w");
       fwrite(rsa_str.toLatin1().data(), rsa_str.size(), 1, fp);
       fclose (fp);
       fp = fopen("/tmp/pub", "r");
       PEM_read_RSAPublicKey(fp, &server_pub_rsa, NULL, NULL);
       fclose (fp);

        from_server_id = rootnode.attributeNode("id").value();

        if(debug_enable)
           qDebug()<<from_server_id;

       timer_heart->start(1000);
             /*只有收到init msg才发射连接成功*/
       emit aes_tcp_connected();

       if(!fix_id.isEmpty()){

           QString bd_info = "<lus_init_msg id=\"@@\" fix_id=\"##\" key_pub=\"%%\" version=\"#ag1\"  group_id=\"#ag2\" />";
           bd_info.replace("##", fix_id);
           bd_info.replace("@@", from_server_id);
           bd_info.replace("%%", QString(local_pub_rsa));
           bd_info.replace("#arg1", lus_version);
           bd_info.replace("#arg2", lus_group_id);
           sendMessage(bd_info.toLatin1(), ENCRYPT_NO);

           if(debug_enable)
               qDebug()<<bd_info;
       }else{
           printf("null fix_id!");
           exit(-1);
       }

       return true;
   }

   if(rootnode.tagName()=="lus_cmd"){


       if(rootnode.attributeNode("body").value() == "ruin"){
           timer_connect->deleteLater();
           exit(0);
       }

       if(rootnode.attributeNode("body").value() == "send_file"){

           qDebug()<<cmd;
           if(debug_enable)
               qDebug() << "send file";
           *s_file_md5 =  rootnode.attributeNode("md5").value();
           qDebug()<<"file md5: "<<*s_file_md5;
           newFileConnect();
           return true;
       }
       return true;
   }

   if(rootnode.tagName() == "lus_term_cmd"){

        prase_terminal_cmd(rootnode);
        return true;
    }

    emit read_xml_msg(rootnode);

    return false;
}

void aes_tcp_lib::update_fix_id()
{
    if(!fix_id.isEmpty()){

        QString bd_info = "<bd_info fix_id=\"##\" version=\"0\" />";
        bd_info.replace("##", fix_id);
        sendMessage(bd_info.toLatin1(), ENCRYPT_YES);
    }
}

QString aes_tcp_lib::lus_get_var_id(void)
{
    return from_server_id;
}

void aes_tcp_lib::lus_down_pool_file(QString index, QString label, QString file_name, QString save_path)
{


   QString cmd = "<lus_requst type=\"file_down\" index=\"@1\" label=\"@2\" file_name=\"@3\" >";

   cmd.replace("@1", index);
   cmd.replace("@2", label);
   cmd.replace("@3", file_name);

   file_save_path = save_path;
   sendMessage(cmd.toLatin1(), ENCRYPT_YES);

}

 void aes_tcp_lib::prase_terminal_cmd(QDomElement rootnode)
 {
    QString str_cmd = rootnode.attributeNode("body").value();

    QStringList arg;
    arg = str_cmd.split(" ");
    str_cmd = arg.at(0);
    arg.removeAt(0);

    QString ret;
    QProcess process;

    process.start(str_cmd, arg); //使用free完成获取
    if(process.waitForFinished(5000)){
        ret = process.readAll();
     }else{
        ret = "timeout!";
    }

    int ex_code = process.exitCode();
    process.close();

    QByteArray byte_xml = "<term_cmd_bak";

    byte_xml += (" body=\"" + ret.toLatin1().toBase64() + "\"");
    byte_xml += (" exit_code=\"" + QString::number(ex_code) + "\"");
    byte_xml += " />";

    if(debug_enable)
        qDebug() <<byte_xml;

    sendMessage(byte_xml, ENCRYPT_NO);


 }
